package com.djz.tool.service;

import com.djz.tool.exception.category.BusinessException;
import com.djz.tool.exception.errorcode.BusinessErrorCode;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.UUID;

@Service
public class VideoServiceImpl implements VideoService {

    private final String uploadDir = "uploads/";

    @Override
    public String saveUploadedFile(MultipartFile file){
        // 确保上传目录存在且有效
        File uploadDirFile = new File(uploadDir);

        // 检查路径是否是目录（如果已存在）
        if (uploadDirFile.exists() && !uploadDirFile.isDirectory()) {
            throw new BusinessException(BusinessErrorCode.SYS_OPR_ERR.getCode(), "Upload path is not a directory: " + uploadDir);
        }

        // 创建目录（包括必要的父目录），失败时抛出异常
        if (!uploadDirFile.exists() && !uploadDirFile.mkdirs()) {
            throw new BusinessException(BusinessErrorCode.SYS_OPR_ERR.getCode(),"Failed to create upload directory: " + uploadDir);
        }

        // 处理原始文件名，防止路径遍历攻击
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || originalFilename.trim().isEmpty()) {
            originalFilename = "unnamed_file"; // 默认文件名
        }

        // 获取安全的文件名（剥离路径信息）
        String safeFilename = Paths.get(originalFilename).getFileName().toString();

        // 生成唯一文件名（时间戳 + UUID 增强唯一性）
        String fileName = String.format("%d_%s_%s",
                System.currentTimeMillis(),
                UUID.randomUUID().toString().substring(0, 8),
                safeFilename);

        // 构建完整文件路径
        File targetFile = new File(uploadDirFile, fileName);
        String filePath = targetFile.getAbsolutePath();

        try (InputStream is = file.getInputStream();
             ReadableByteChannel sourceChannel = Channels.newChannel(is);
             FileChannel destChannel = FileChannel.open(
                     targetFile.toPath(),
                     StandardOpenOption.WRITE,
                     StandardOpenOption.CREATE)) {
            // 使用 transferFrom 方法传输数据（零拷贝，高效）
            destChannel.transferFrom(sourceChannel, 0, Long.MAX_VALUE);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return filePath;
    }

}
